
//--------------------------------------------------------------------------------------------------------
// Module  : fpga_top_usb_audio
// Type    : synthesizable, fpga top
// Standard: Verilog 2001 (IEEE1364-2001)
// Function: example for usb_audio_top
//--------------------------------------------------------------------------------------------------------

module fpga_top_usb_audio (
    // clock
    input  wire        clk27mhz,     // connect to a 27MHz oscillator
    // reset button
    input  wire        button,       // connect to a reset button, 0=reset, 1=release. If you don't have a button, tie this signal to 1.
    input wire         spieed_en,
    // LED
    output wire        led,          // 1: USB connected , 0: USB disconnected
    // USB signals
    output wire        usb_dp_pull,  // connect to USB D+ by an 1.5k resistor
    inout              usb_dp,       // connect to USB D+
    inout              usb_dn,       // connect to USB D-
    // debug output info, only for USB developers, can be ignored for normally use
    output wire        uart_tx,       // If you want to see the debug info of USB device core, please connect this UART signal to host-PC (UART format: 115200,8,n,1), otherwise you can ignore this signal.
    //microphone
    input [3:0] mic_data,
    output clk_ws,
    output clk_3m,
    //pt8211接口
    output       HP_BCK   , //同clk_1m5
    output       HP_WS    , //左右声道切换信号，低电平对应左声道
    output       HP_DIN   , //dac串行数据输入信号
    output       PA_EN     , //音频功放使能，高电平有效
    //sk9822接口
    output      sk9822_ck,
    output      sk9822_da
);



//-------------------------------------------------------------------------------------------------------------------------------------
// The USB controller core needs a 60MHz clock, this PLL module is to convert clk27mhz to clk60mhz
// If you use other FPGA families, please use their compatible primitives or IP-cores to generate clk60mhz
//-------------------------------------------------------------------------------------------------------------------------------------
//1.led 标识是否已经连接到USB设备
wire led_n;
assign led = ~led_n;
 //2.构造出所需要的时钟主频
wire       clk60mhz;
Gowin_rPLL your_instance_name(
        .clkout(clk60mhz), //output clkout
        .clkin(clk27mhz) //input clkin
);

wire signed [15:0] audio_l_final, audio_r_final;
wire signed [15:0] audio_l_process, audio_r_process;
assign audio_l_final = spieed_en ? audio_l_process : mic_1[23:8];
assign audio_r_final = spieed_en ? audio_r_process : mic_0[23:8];
//3.iis接受原始的麦克风数据（串行16位有符号数）
wire signed [23:0] mic_0;
wire signed [23:0] mic_1;
wire signed [23:0] mic_2;
wire signed [23:0] mic_3;
wire signed [23:0] mic_4;
wire signed [23:0] mic_5;

wire finished_temp1;
wire rst_dsp = button&(!finished_temp1);
wire start_mic;
wire finished_left,finished_right;

mic_serial mic_serial_inst (
    .clk(clk27mhz),    
    .rst_n(button),
    .rst_dsp(rst_dsp),
    .mic_clk(clk_3m),
    .mic_ws(clk_ws),
    .mic_so(mic_data),
    .mic_0(mic_0),
    .mic_1(mic_1),
    .mic_2(mic_2),
    .mic_3(mic_3),
    .mic_4(mic_4),
    .mic_5(mic_5),
    .finished_left1(finished_left),
    .finished_right1(finished_right),
    .start(start_mic)
);


//4.通过多路信号计算互相关，计算出声源的大致方位，并选择合适的收音信道
wire finished;
wire [5:0] sequence1;
wire [5:0] sequence2;
wire [5:0] sequence3;
reg  [31:0] max_sequence_x;
reg [31:0] max_sequence_y;
xcorr xcorr1(
    .clk(clk27mhz),
    .rst_n(rst_dsp),
    .start_flag(start_mic),
    .finish_left(finished_left),
    .finish_right(finished_right),
    .mic_1(mic_2[23:6]),
    .mic_2(mic_5[23:6]),
    .sequence_num(sequence1),
    .finished(finished),
    .finished_temp1(finished_temp1)
);
xcorr xcorr2(
    .clk(clk27mhz),
    .rst_n(rst_dsp),
    .start_flag(start_mic),
    .finish_left(finished_left),
    .finish_right(finished_right),
    .mic_1(mic_0[23:6]),
    .mic_2(mic_3[23:6]),
    .sequence_num(sequence2),
    .finished(),
    .finished_temp1()
);
xcorr xcorr3(
    .clk(clk27mhz),
    .rst_n(rst_dsp),
    .start_flag(start_mic),
    .finish_left(finished_left),
    .finish_right(finished_left),
    .mic_1(mic_1[23:6]),
    .mic_2(mic_4[23:6]),
    .sequence_num(sequence3),
    .finished(),
    .finished_temp1()
);
//5.根据互相关的数据，点亮对应的SK9822灯
mic_led sk9822_dir(
    .clk(clk27mhz),
    .mic1(sequence1),
    .mic2(sequence2),
    .mic3(sequence3),
    .tVAD(tVAD),

    .sk9822_ck(sk9822_ck),
    .sk9822_da(sk9822_da),
    .direction(),
    .direction2(),
    .direction3()
);
//6.USB的扬声器和麦克风的接口
wire [10:0] audio_1250_cnt;
usb_audio_top #(
    .DEBUG           ( "FALSE"             )    // If you want to see the debug info of USB device core, set this parameter to "TRUE"
) u_usb_audio (
    .rstn            ( button ),
    .clk             ( clk60mhz            ),
    // USB signals
    .usb_dp_pull     ( usb_dp_pull         ),
    .usb_dp          ( usb_dp              ),
    .usb_dn          ( usb_dn              ),
    // USB reset output
    .usb_rstn        ( led_n              ),   // 1: connected , 0: disconnected (when USB cable unplug, or when system reset (rstn=0))
    // user data : audio output (host-to-device, such as a speaker), and audio input (device-to-host, such as a microphone).
    .audio_en        (   data_async               ),
    .audio_lo        (  audio_lo            ),   // left-channel output : 16-bit signed integer, which will be valid when audio_en=1
    .audio_ro        (  audio_ro            ),   // right-channel output: 16-bit signed integer, which will be valid when audio_en=1
    .audio_li        (   audio_l_final  ),   // left-channel input  : 16-bit signed integer, which will be sampled when audio_en=1
    .audio_ri        (   audio_r_final  ),   // right-channel input : 16-bit signed integer, which will be sampled when audio_en=1
    // debug output info, only for USB developers, can be ignored for normally use
    .debug_en        (                     ),
    .debug_data      (                     ),
    .debug_uart_tx   ( uart_tx             ),
    // sheiyi added
    .clk_1p536m   (usb_clk_1p536),  //usb扬声器数据同步信号
    .audio_en_total    (    data_valid   ),
    .cnt                 ( audio_1250_cnt  )
);
//7.算法运算进行功能实现
wire data_async;
wire data_valid;
wire tVAD;
AUDIO_PROCESS dsp_shei_t(
    .clk_60m(clk60mhz),
    .rst_n(button),
    .audio_r(mic_0[23:8]),
    .audio_l(mic_1[23:8]),
    .speaker_l(16'd0),
    .speaker_r(16'd0),
    .data_async(data_async),
    .data_valid(data_valid),
    .pos_cnt(audio_1250_cnt),

    .o_audio_r(audio_r_process),
    .o_audio_l(audio_l_process),
    .tVAD(tVAD)
);
//8.扬声器的输出
wire signed [15:0] audio_lo, audio_ro;
wire signed [15:0] audio_lo_final, audio_ro_final;
parameter signed HIGH_GATE = 16'd15000;//构造有符号数的比较
parameter signed LOW_GATE = -16'd15000;
assign audio_lo_final = (audio_lo <= HIGH_GATE && audio_lo >= LOW_GATE) ? audio_lo : 16'd0;//去除输入信号的爆破声、电流声
assign audio_ro_final = (audio_ro <= HIGH_GATE && audio_ro >= LOW_GATE) ? audio_ro : 16'd0;
wire usb_clk_1p536;
speaker my_spk(
    .clk_1p536m(usb_clk_1p536),//1.536Mhz
    .rst_n(button),
    .Ldata(audio_lo_final),
    .Rdata(audio_ro_final),
    //pt8211接口
    .HP_BCK(HP_BCK), //同clk_1m5
    .HP_WS(HP_WS), //左右声道切换信号，低电平对应左声道
    .HP_DIN(HP_DIN), //dac串行数据输入信号
    .PA_EN(PA_EN)//音频功放使能，高电平有效
);

endmodule
